package de.ipk_gatersleben.bit.bi.edal.publication.attribute.panel;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.swing.BorderFactory;
import javax.swing.CellEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.MatteBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

import de.ipk_gatersleben.bit.bi.edal.primary_data.metadata.NaturalPerson;
import de.ipk_gatersleben.bit.bi.edal.publication.AttributeLabel;
import de.ipk_gatersleben.bit.bi.edal.publication.AttributeTablePanel;
import de.ipk_gatersleben.bit.bi.edal.publication.Utils;
import de.ipk_gatersleben.bit.bi.edal.publication.PropertyLoader;
import de.ipk_gatersleben.bit.bi.edal.publication.PublicationFrame;
import de.ipk_gatersleben.bit.bi.edal.publication.PublicationMainPanel;
import de.ipk_gatersleben.bit.bi.edal.publication.PublicationModul;

public class AuthorsPanel extends JPanel implements ActionListener {

	private static final long serialVersionUID = 8109825692298261311L;

	private static final AttributeLabel AUTHORS_LABEL = new AttributeLabel(
			PropertyLoader.props.getProperty("AUTHORS_LABEL"),
			PropertyLoader.props.getProperty("AUTHORS_TOOLTIP"));

	private static final JButton OKAY_BUTTON = new JButton("OK");
	private static final JButton ADD_BUTTON = new JButton("ADD AUTHOR");
	private static final JButton REMOVE_BUTTON = new JButton("REMOVE AUTHOR");

	private DefaultTableModel model;
	private JTable table;
	private DefaultComboBoxModel<String> comboModel;

	private static final String CORRESPONDING_AUTOR = "Corresponding author";
	private static final String CONTRIBUTOR = "Contributor";

	private static final String[] value = { CORRESPONDING_AUTOR, CONTRIBUTOR };

	private static final String[] DEFAULT_AUTHOR_VALUE = new String[] {
			value[0], "", "", "Corrensstraße 3", "06466 Gatersleben", "Germany" };

	private static final String[] DEFAULT_CONTRIBUTOR_VALUE = new String[] {
			value[1], "", "", "Corrensstraße 3", "06466 Gatersleben", "Germany" };

	private static final String[] COL_NAMES = { "Role", "Given Name",
			"Sure Name", "Address", "Zip", "Country" };

	public AuthorsPanel() {

		GridBagLayout grid = new GridBagLayout();

		JPanel mainPanel = new JPanel(grid);

		mainPanel.setBackground(PropertyLoader.MAIN_BACKGROUND_COLOR);

		model = new MyTableModel();
		table = new JTable(model);

		table.setFillsViewportHeight(true);
		table.setFont(PropertyLoader.DEFAULT_FONT);
		table.setForeground(PropertyLoader.MAIN_FONT_COLOR);
		table.getTableHeader().setFont(PropertyLoader.DEFAULT_FONT);
		table.getTableHeader().setForeground(PropertyLoader.MAIN_FONT_COLOR);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.getTableHeader().setBorder(
				BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));

		comboModel = new DefaultComboBoxModel<String>(value);
		JComboBox<String> comboRow = new JComboBox<String>();
		comboRow.setModel(comboModel);
		TableColumn col = table.getColumnModel().getColumn(0);
		col.setCellEditor(new DefaultCellEditor(comboRow));

		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
		buttonPanel.setBackground(PropertyLoader.MAIN_BACKGROUND_COLOR);

		buttonPanel.add(OKAY_BUTTON);
		buttonPanel.add(ADD_BUTTON);
		buttonPanel.add(REMOVE_BUTTON);

		OKAY_BUTTON.addActionListener(this);
		ADD_BUTTON.addActionListener(this);
		REMOVE_BUTTON.addActionListener(this);

		JScrollPane scrollPane = new JScrollPane(table);
		scrollPane.setPreferredSize(new Dimension(
				PropertyLoader.MINIMUM_DIM_PUBLICATION_FRAME.width,
				PropertyLoader.AUTHOR_PANEL_HEIGHT));

		Utils.addComponent(mainPanel, grid, scrollPane, 0, 0, 1, 1, 1, 0.95, 1,
				1);
		Utils.addComponent(mainPanel, grid, buttonPanel, 0, 1, 1, 1, 1, 0.05,
				1, 1);

		JPanel attributePanel = new JPanel(new BorderLayout());

		AuthorsPanel.AUTHORS_LABEL.setForeground(PropertyLoader.LABEL_COLOR);

		attributePanel.add(AuthorsPanel.AUTHORS_LABEL, BorderLayout.NORTH);
		attributePanel.setBackground(PropertyLoader.MAIN_BACKGROUND_COLOR);
		attributePanel.setPreferredSize(new Dimension(40,
				PropertyLoader.AUTHOR_PANEL_HEIGHT));

		this.setBorder(new MatteBorder(0, 0, 1, 0, Color.BLACK));

		GridBagLayout gridbaglayout = new GridBagLayout();

		this.setLayout(gridbaglayout);
		this.setBackground(PropertyLoader.MAIN_BACKGROUND_COLOR);

		Utils.addComponent(this, gridbaglayout, attributePanel, 0, 0, 1, 1,
				0.02, 1, 50, 10);
		Utils.addComponent(this, gridbaglayout, mainPanel, 1, 0, 1, 1, 0.98, 1,
				50, 10);

	}

	@Override
	public void actionPerformed(ActionEvent actionEvent) {

		if (actionEvent.getSource().equals(OKAY_BUTTON)) {

			CellEditor cellEditor = table.getCellEditor();
			if (cellEditor != null) {
				if (cellEditor.getCellEditorValue() == null) {
					cellEditor.stopCellEditing();
				}
			}

			/* clear(unselect) selected rows */
			this.table.clearSelection();
			this.comboModel.setSelectedItem(this.comboModel.getSelectedItem());
			/* remove rows without any name */
			ArrayList<Integer> emptyLines = new ArrayList<Integer>();

			for (int i = 0; i < this.table.getRowCount(); i++) {
				if (Utils.checkIfStringIsEmpty(this.model.getValueAt(i, 2)
						.toString())
						&& Utils.checkIfStringIsEmpty(this.model.getValueAt(i,
								1).toString())) {
					emptyLines.add(i);
				}
			}

			for (int i = emptyLines.size() - 1; i >= 0; i--) {
				this.model.removeRow(emptyLines.get(i));
			}

			PublicationMainPanel.authorPanel = this;

			PublicationMainPanel.authorsField.setText(getTableContent());

			PublicationMainPanel.releaseAllBlockedFields();

			PublicationMainPanel.getMainPanel().remove(
					PublicationMainPanel.AUTHOR_PANEL_COMPONENT_NUMBER);

			PropertyLoader.AUTHORS_LABEL
					.setForeground(PropertyLoader.LABEL_COLOR);

			PublicationMainPanel.getMainPanel().add(
					new AttributeTablePanel(PropertyLoader.AUTHORS_LABEL,
							PublicationMainPanel.authorsField,
							(PropertyLoader.THREE_TIMES_SIZE)),
					PublicationMainPanel.AUTHOR_PANEL_COMPONENT_NUMBER);

			PublicationFrame.updateUI();
			PublicationModul.getFrame().requestFocusInWindow();

		} else if (actionEvent.getSource().equals(ADD_BUTTON)) {

			boolean authorSetted = false;

			for (int i = 0; i < this.table.getRowCount(); i++) {
				if (this.table.getValueAt(i, 0).toString()
						.equals(value[0].toString())) {
					authorSetted = true;
					break;
				}
			}

			if (this.table.getSelectedRow() != -1) {
				if (authorSetted) {
					this.model.insertRow(this.table.getSelectedRow() + 1,
							DEFAULT_CONTRIBUTOR_VALUE);
				} else {
					this.model.insertRow(this.table.getSelectedRow() + 1,
							DEFAULT_AUTHOR_VALUE);
				}

			} else {
				if (authorSetted) {
					this.model.addRow(DEFAULT_CONTRIBUTOR_VALUE);
				} else {
					this.model.addRow(DEFAULT_AUTHOR_VALUE);

				}
			}

		}

		else if (actionEvent.getSource().equals(REMOVE_BUTTON)) {

			if (this.model.getRowCount() != 0) {
				if (this.table.getSelectedRow() != -1) {

					this.model.removeRow(this.table.getSelectedRow());
				} else {
					this.model.removeRow(this.model.getRowCount() - 1);
				}
			}
		}

	}

	private class MyTableModel extends DefaultTableModel {

		private static final long serialVersionUID = 8557354261856948625L;

		private Object[][] data = { DEFAULT_AUTHOR_VALUE };

		public MyTableModel() {
			setDataVector(data, COL_NAMES);
		}
	}

	private String getTableContent() {

		if (this.getCreators().length == 0) {
			return PublicationMainPanel.DEFAULT_AUTHORS_STRING;
		}

		String authorSeperator = new String("; ");
		String nameSeperator = new String(", ");

		StringBuffer buffer = new StringBuffer("");

		for (int i = 0; i < this.model.getRowCount(); i++) {
			if (!Utils.checkIfStringIsEmpty(this.model.getValueAt(i, 2)
					.toString())
					&& !Utils.checkIfStringIsEmpty(this.model.getValueAt(i, 1)
							.toString())) {
				buffer.append(this.model.getValueAt(i, 2).toString());
				buffer.append(nameSeperator);
				buffer.append(this.model.getValueAt(i, 1).toString());
				buffer.append(authorSeperator);
			}

			else if (!Utils.checkIfStringIsEmpty(this.model.getValueAt(i, 1)
					.toString())) {
				buffer.append(this.model.getValueAt(i, 1).toString());
				buffer.append(authorSeperator);
			} else if (!Utils.checkIfStringIsEmpty(this.model.getValueAt(i, 2)
					.toString())) {
				buffer.append(this.model.getValueAt(i, 2).toString());
				buffer.append(authorSeperator);
			} else {
				// nothing
			}
		}

		if (buffer.toString().lastIndexOf(authorSeperator) != -1) {
			return buffer.toString().substring(0,
					buffer.toString().lastIndexOf(authorSeperator));
		} else {
			return PublicationMainPanel.DEFAULT_AUTHORS_STRING;
		}
	}

	public NaturalPerson[] getCreators() {
		LinkedList<NaturalPerson> creators = new LinkedList<NaturalPerson>();

		for (int i = 0; i < this.model.getRowCount(); i++) {
			if (this.model.getValueAt(i, 0).toString()
					.equals(CORRESPONDING_AUTOR)) {
				creators.add(new NaturalPerson(this.model.getValueAt(i, 1)
						.toString(), this.model.getValueAt(i, 2).toString(),
						this.model.getValueAt(i, 3).toString(), this.model
								.getValueAt(i, 4).toString(), this.model
								.getValueAt(i, 5).toString()));
			}
		}
		return creators.toArray(new NaturalPerson[creators.size()]);

	}

	public NaturalPerson[] getContributors() {
		LinkedList<NaturalPerson> contributors = new LinkedList<NaturalPerson>();

		for (int i = 0; i < this.model.getRowCount(); i++) {
			if (this.model.getValueAt(i, 0).toString().equals(CONTRIBUTOR)) {
				contributors.add(new NaturalPerson(this.model.getValueAt(i, 1)
						.toString(), this.model.getValueAt(i, 2).toString(),
						this.model.getValueAt(i, 3).toString(), this.model
								.getValueAt(i, 4).toString(), this.model
								.getValueAt(i, 5).toString()));
			}
		}
		return contributors.toArray(new NaturalPerson[contributors.size()]);

	}

	public String getAuthors() {

		String authorSeperator = new String("; ");
		String nameSeperator = new String(", ");

		StringBuffer buffer = new StringBuffer("");

		for (int i = 0; i < this.model.getRowCount(); i++) {
			if (this.model.getValueAt(i, 0).equals(value[0])) {
				if (!Utils.checkIfStringIsEmpty(this.model.getValueAt(i, 2)
						.toString())
						&& !Utils.checkIfStringIsEmpty(this.model.getValueAt(i,
								1).toString())) {
					buffer.append(this.model.getValueAt(i, 2).toString());
					buffer.append(nameSeperator);
					buffer.append(this.model.getValueAt(i, 1).toString());
					buffer.append(authorSeperator);
				}

				else if (!Utils.checkIfStringIsEmpty(this.model
						.getValueAt(i, 1).toString())) {
					buffer.append(this.model.getValueAt(i, 1).toString());
					buffer.append(authorSeperator);
				} else if (!Utils.checkIfStringIsEmpty(this.model.getValueAt(i,
						2).toString())) {
					buffer.append(this.model.getValueAt(i, 2).toString());
					buffer.append(authorSeperator);
				} else {
					// do nothing
				}
			}

		}

		if (buffer.toString().lastIndexOf(authorSeperator) != -1) {
			return buffer.toString().substring(0,
					buffer.toString().lastIndexOf(authorSeperator));
		} else {
			return PublicationMainPanel.DEFAULT_AUTHORS_STRING;
		}
	}

	public void reset() {
		this.model = new MyTableModel();
		this.table = new JTable(this.model);
	}

}
